package hn.cch.async.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Service
public class AsyncServiceImpl implements AsyncService {

    private static final Logger logger = LoggerFactory.getLogger(AsyncServiceImpl.class);


    public void run(long wait) {
        try {
            Thread.sleep(wait * 1000);
        } catch (InterruptedException e) {
            logger.error(e.getMessage());
        }
    }

    public void sync() {
        logger.info("sync return void start");
        run(3);// code
        logger.info("sync return void stop");
    }

    public Future<String> sync(String string) {
        logger.info("sync return Future start");
        Future<String> future = Executors.newSingleThreadExecutor().submit(() -> {
            logger.info("submit");
            run(30);// code
            logger.info("return");
            return string;
        });
        logger.info("sync return Future stop");
        return future;
    }


    @Async(value = "threadPool")
    public void async() {
        logger.info("async return void start");
        run(3);// code
        logger.info("async return void stop");
    }

    @Async
    public Future<String> async(String string) {
        logger.info("async return Future start");
        run(3);// code
        Future<String> future = new AsyncResult<>(string);
        logger.info("async return Future stop");
        return future;
    }


    @Async
    public Future<String> async(String string, CountDownLatch countDownLatch) {
        logger.info("async return Future start");
        run(10);// code
        Future<String> future = new AsyncResult<>(string);
        logger.info("async return Future stop");
        countDownLatch.countDown();
        return future;
    }

}
